firebaseてめえ


概要

iOSアプリをAppTransferすると、firebase cloud messagingの通知が最低10日の間不完全な状態になる。有り体に言うと死ぬ。

これは開発者側からは何もできることはない。10日間絶え間なく12の型を繋げていれば(サポートとやり取りしていれば)いつの間にか解決する。おクソでございますわね。



Transferすると何が起きるのか

fcmに登録する要素として、APNs関連のAuthorization KeyとTeamIDの2つがあり、これらがTransfer前とTransfer後で当然変わる。


そしてTransferに際して、これらのfcmのパラメータを変更したが最後、いや変更するしかないんだが、

・旧来のTeamIDのユーザーへの通知が全て死ぬ

・新規のTeamIDのユーザーへの通知がだんだんと有効になる

ということが起きる。


具体例としては、

Aさん、Bさんという2名のiOSAppユーザーがいた時、AppTransferの瞬間からAさん、Bさんへのpushは404エラーを返すようになり、

Aさんは2日後にはpushが届くようになり、Bさんはなんと10日後にpushが届くようになる。


何故こうなるのか

一部、Firebaseの内部IDに対してのみ俺の憶測が入る。他は観測した。


firebase cloud messagingのiOS関連のアカウントは、2020/07現在、次のような形式でAPNsとの連携を実装している。


FirebasePushUserID(仮) - firebase push token

\_ APNs token


FirebasePushUserID(FPUID) は適当に外部から想像する代物なんだけど、pushに関して、firebaseが管理するこのようなデータ構造がユーザー単位で存在すると思いねえ。


firebase push tokenは7dayくらいの寿命を持ち、例えばUnity firebase cloud messaging SDKは、1W(7day)に一度、firebaseから新しいfirebase push token(FPToken)を受け取る。

これにより、FPUIDに紐づくFPTokenが更新される。端末とかは変わってないので、APNs tokenは変わらない、みたいな状態が起きる。


FirebasePushUserID(仮) - firebase push token <- こいつが更新される

\_ APNs token <- このへんは変わらない


App側はそのFPTokenを自社のWebサーバとかに送付して、以降push通知を流したいタイミングで、次のような通信を行う。


Webサーバ(FPToken使用) -> fcm(紐づくAPNs使用) -> ユーザーデバイスに通知が届く


これが正常系。まあそれはいい。


でねーこれねー、Transferがあったタイミング以降で、FPTokenが更新されても、一定期間、Webサーバ-fcm間で404エラーが出るんだよね。


いやFPTokenの寿命が1Wって言ってるから、そりゃ更新されるタイミングはTransferから最大1Wなのでは?って思うじゃん? 違うんだよ。


fcmは、Transfer以後にたまたま寿命を迎えたFPTokenが更新されても、FPTokenを強制的に更新しても、10日間くらいの間は、404エラーになるようなFPTokenを返してくるんだよね。



は?っていうね。 更新したのに404なのかよ。



次のようなパターンがあるのを確認している。

case 1. Transfer以降で、App起動時に1Wに一度、fcmから新しいFPTokenを取得できるが、そのFPTokenは404エラーになる

case 2. Transfer以降で、Appのpush通知設定を変更することでfcmから新しいFPTokenを取得できるが、そのFPTokenは404エラーになる

case 3. Transfer以降で、Appを新規インストール/再インストール(削除してから再インストール!)した場合、それ以降に取得できるFPTokenは正常な動作をする(が、どうやって促すんだよ、push届かねえんだっつうの)

case 4. Transfer以降で、Appを更新した場合、それ以降に取得できるFPTokenは正常な動作をする(らしい、未確認、いやでもお前どうやって促すんだよ、push届かねえんだっつうの)


というような感じになっている。case 1, 2, 3, 4全部に問題がある。なんだこれ地獄かね。



Transferから10日間が過ぎたあたりで、FPTokenが更新された以降で404が出なくなる。404が出ない状態のFPTokenが配布され始めるんだ。

だんだんとpush失敗のログから404が減っていき、ついにはTransfer前と同等に戻る。


これは繰り返しになるが、FPTokenの更新頻度は関係ない。真っ当な、404エラーにならないFPTokenがfirebaseから確実に取得できるのが、Transferから10日以降なのだ。

もちろんばらつきはある。このばらつきによって、Transferから1度目のFPToken更新で404にならないFPTokenを引けるユーザもいれば、そうではなくハズレFPTokenを得るユーザーもいる。



firebase側もこの状態になったときに何かできるかというと何もできない。開発者も何もできないしfirebase側も何もできない。最悪の体験だった。

firebaseよ、こうなるのを知っとけ。ドキュメントに書いとけ。OK? みたいな。ふふ。



エラーが最悪

このcase 1,2で発生する404エラーは、通常のfcmが返してくる「お前が指定した端末はそんざいしないゾ☆」エラーと見分けがつかない。

突然404エラーが増えて見えるわけで、は? ってなるが、まあ、何もできない。



どう回避すればいいのか

Transfer時にfcmを使わない。

自前でAPNs tokenを保持しておき、Transferから10dayか2W(14day)経過するまでは、自前でAPNs tokenを使ってpushする。



もしこうなったときに、やった方がいいこと

Transfer後、即iOSアプリの審査を登録しても2-3日、それが全ユーザーに知れ渡るまでに4-5日、その間は無防備睡眠状態で殴られ続ける。

pushは届かない。お知らせもユーザーがアプリを起動するまで無意味。唯一アプリ入れ直しだけが意味を成すが、いや、ユーザーにそれをさせちゃダメでしょ。正気を疑う。


こうなってしまった場合にできることはない。何をしても無駄。

こうなる前に、やった方がいいこと

Firebase Cloud MessagingのUnity SDKは、まあiOS SDKもだが、APNsを取得するルートをmethod swizzlingによってAppから奪うことで動作している。

これさーマジでさー、この構造やめてくんねーかなー、せめて一瞬でいいからUnityとかiOSにも取得チャンスくれや、改造すんぞ。


ということで改造しましょう。APNsを取り戻しつつfcmにもFPTokenを作ってもらう。